

#include <stdint.h>
#include <stdbool.h>
#include "pcf8575.h"
#include "system_definitions.h"
#include "os.h"

#define W_BYTE	0X40 
#define R_BYTE	0X41 

uint16_t led_state_now; //当前LED接口的状态。

OS_SEM   iic4_lock_sem;

typedef struct{
	uint8_t dev_addr;
	void (*IIC_SEND_BYTE)(uint8_t data);	
	uint8_t (*IIC_RECV_BYTE)(void);
}PCF8575_Block_T;

/* Delay routine to provide application level delays*/
//
void delay_some_iic(unsigned int delay)
{
	while (delay > 0){
		delay--;
		asm("nop");
	}
}

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  pcf8575_write_data
 *  Description:  
 * =====================================================================================
 */
//void pcf8575_write_data(PCF8575_Block_T *ptr, uint16_t data){
uint8_t pcf8575_write_data(uint16_t data){

	uint8_t ret;

        ret = OSAL_SEM_Pend(&iic4_lock_sem, 5); 			/*等待信号量*/
        if(ret != DEF_OK){
            OSAL_SEM_Post(&iic4_lock_sem);
            return false;
        }
//	DRV_I2C1_DeInitialize();
//        delay_some_iic(5);
//	DRV_I2C1_Initialize();
        I2C4CONbits.ON = 0;
        delay_some_iic(5);
        I2C4CONbits.ON = 1;

//	ret = DRV_I2C1_MasterRestart();
//	if(ret == false){
//		return false;
//	}
//        delay_some_iic(5);
	ret = DRV_I2C1_MasterStart();
	if(ret == false){
                OSAL_SEM_Post(&iic4_lock_sem); 			/*等待信号量*/
		return false;
	}
	//	delay_some(5000);
	ret = DRV_I2C1_WaitForStartComplete();
	if(ret == false){
                OSAL_SEM_Post(&iic4_lock_sem);
		return false;
	}
	ret = DRV_I2C1_ByteWrite(W_BYTE);                        //写入地址
	if(ret == false){
                OSAL_SEM_Post(&iic4_lock_sem);
		return false;
	}
	ret = DRV_I2C1_WaitForByteWriteToComplete();             //等待应答
	if(ret == false){
                OSAL_SEM_Post(&iic4_lock_sem);
		return false;
	}
	if(DRV_I2C1_WriteByteAcknowledged()){
		ret = DRV_I2C1_ByteWrite((data >> 0) & 0x00ff);  //写入数据低位
		if(ret == false){
                    OSAL_SEM_Post(&iic4_lock_sem);
			return false;
		}
		ret = DRV_I2C1_WaitForByteWriteToComplete();     //等待应答
		if(ret == false){
                    OSAL_SEM_Post(&iic4_lock_sem);
			return false;
		}
		ret = DRV_I2C1_ByteWrite((data >> 8) & 0x00ff);  //写入数据高位
		if(ret == false){
                    OSAL_SEM_Post(&iic4_lock_sem);
			return false;
		}
		ret = DRV_I2C1_WaitForByteWriteToComplete();     //等待应答
		if(ret == false){
                    OSAL_SEM_Post(&iic4_lock_sem);
			return false;
		}
	}

	//	delay_some(5000);
	ret = DRV_I2C1_MasterStop();
	if(ret == false){
            OSAL_SEM_Post(&iic4_lock_sem);
		return false;
	}
	//	DRV_I2C1_WaitForStopComplete();

	//	while(!DRV_I2C1_MasterBusIdle());
	//	DRV_I2C1_MasterStop();
        OSAL_SEM_Post(&iic4_lock_sem);
	return true;
}		/* -----  end of function pcf8575_write_data  ----- */


/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  pcf8575_led_on
 *  Description:  点亮LED
 * =====================================================================================
 */
void pcf8575_led_off(uint16_t led_id){

	uint8_t ret;
	uint16_t temp = (led_state_now | led_id);
	ret = pcf8575_write_data(temp);
	if(ret == true){
		led_state_now |= led_id;
        }else{

        }

	return ;
}		/* -----  end of function pcf8575_led_on  ----- */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  pcf8575_led_off
 *  Description:  关闭LED
 * =====================================================================================
 */
void pcf8575_led_on(uint16_t led_id){

	uint8_t ret;
	uint16_t temp = (led_state_now & (~led_id));

//	led_state_now &= (~led_id);
	ret = pcf8575_write_data(temp);
	if(ret == true){
//		led_state_now &= (~led_id);
		led_state_now = temp;
        }else{
        
        }

	return ;
}		/* -----  end of function pcf8575_led_off  ----- */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  pcf8575_led_toggle
 *  Description:  翻转LED
 * =====================================================================================
 */
void pcf8575_led_toggle(uint16_t led_id){

	uint16_t temp = 0;
	temp = led_id & led_state_now;
	if(temp == 0x0000){
		pcf8575_led_off(led_id);
	}else{
		pcf8575_led_on(led_id);
	}

	return ;
}		/* -----  end of function pcf8575_led_toggle  ----- */

